/***
 * @Author: 玄绮 shijiahansi@qq.com
 * @Date: 2024-05-06 14:18:52
 * @LastEditors: 玄绮 shijiahansi@qq.com
 * @LastEditTime: 2024-05-06 14:23:16
 * @FilePath: \protobuff_learn\src\proto\packge.h
 * @Description:
 * @
 * @Copyright (c) 2024 by 玄绮, All Rights Reserved.
 */

#ifndef __PACKGE_H__
#define __PACKGE_H__

#include <cstddef>
#include <cstdint>
#include <google/protobuf/message.h>
#include <memory>
#include <packge/PackgeType.pb.h>
#include <string>
#include <string_view>

namespace proto {
    namespace packge {

        enum ProtoType : uint8_t {
            ProtoBuf = 0,
            JSON     = 1
        };
        enum Version : uint8_t {
            VERSION10 = 10
        };

        struct Header
        {
            uint32_t body_length;
            PackgeType packge_type;
            ProtoType proto_type;
            Version version;
        };

        struct Packge
        {
            using shared_ptr = std::shared_ptr<Packge>;
            using data_type  = std::string;
            
            static shared_ptr make_shared() {
                return std::make_shared<Packge>();
            }

            enum {
                HeaderLength     = sizeof(Header),
                base_body_length = 128
            };

            void setType(PackgeType type) {
                header.packge_type = type;
            }

            PackgeType type() {
                return header.packge_type;
            }

            Packge() { data.resize(HeaderLength + base_body_length); }

            /**
             * @brief 解码
             *
             * @param msg
             * @return true
             * @return false
             */
            bool decode(::google::protobuf::Message* msg);

            /**
             * @brief 编码
             *
             * @param msg
             * @return true
             * @return false
             */
            bool encode(::google::protobuf::Message* msg);

            bool SerializeToString(std::string& ss);
            bool ParseFromString(std::string_view ss);

            // private:
            Header header;
            data_type data;
        };

    }  // namespace packge
}  // namespace proto

#endif  // __PACKGE_H__
